/*
 *  Brute force base64 decode test, try to cover all code paths and all
 *  lookup table indices.
 */

/*@include util-string.js@*/

/*---
custom: true
---*/

/*===
concatenate
358810080
whitespace and mutate test
0 0 0
1 4 21198057
2 4 21198747
3 4 21202557
4 4 21203247
5 4 21200817
6 4 21201507
7 4 21205317
8 4 21206007
9 4 21209817
10 4 21210507
11 4 21228747
12 4 21229437
13 4 21233247
14 4 21233937
15 4 21237747
16 4 21238437
17 4 21198471
18 4 21199161
19 4 21202971
20 4 21203661
21 4 21201231
22 4 21201921
23 4 21205731
24 4 21206421
25 4 21210231
26 4 21210921
27 4 21229161
28 4 21229851
29 4 21233661
30 4 21234351
31 4 21238161
32 4 21238851
33 4 21198885
34 4 21199575
35 4 21203385
36 4 21204075
37 4 21201645
38 4 21202335
39 4 21206145
40 4 21206835
41 4 21210645
42 4 21211335
43 4 21229575
44 4 21230265
45 4 21234075
46 4 21234765
47 4 21238575
48 4 21239265
49 4 21199299
50 4 21199989
51 4 21203799
52 4 21204489
53 4 21202059
54 4 21202749
55 4 21206559
56 4 21207249
57 4 21211059
58 4 21211749
59 4 21229989
60 4 21230679
61 4 21234489
62 4 21235179
63 4 21238989
64 4 21239679
65 4 21199713
66 4 21200403
67 4 21204213
68 4 21204903
69 4 21202473
70 4 21203163
71 4 21206973
72 4 21207663
73 4 21211473
74 4 21212163
75 4 21230403
76 4 21231093
77 4 21234903
78 4 21235593
79 4 21239403
80 4 21240093
81 4 21200127
82 4 21200817
83 4 21204627
84 4 21205317
85 4 21202887
86 4 21203577
87 4 21207387
88 4 21208077
89 4 21211887
90 4 21212577
91 4 21230817
92 4 21231507
93 4 21235317
94 4 21236007
95 4 21239817
96 4 21240507
97 4 21200541
98 4 21201231
99 4 21205041
100 4 21205731
101 4 21203301
102 4 21203991
103 4 21207801
104 4 21208491
105 4 21212301
106 4 21212991
107 4 21231231
108 4 21231921
109 4 21235731
110 4 21236421
111 4 21240231
112 4 21240921
113 4 21200955
114 4 21201645
115 4 21205455
116 4 21206145
117 4 21203715
118 4 21204405
119 4 21208215
120 4 21208905
121 4 21212715
122 4 21213405
123 4 21231645
124 4 21232335
125 4 21236145
126 4 21236835
127 4 21240645
128 4 21241335
129 4 21201369
130 4 21202059
131 4 21205869
132 4 21206559
133 4 21204129
134 4 21204819
135 4 21208629
136 4 21209319
137 4 21213129
138 4 21213819
139 4 21232059
140 4 21232749
141 4 21236559
142 4 21237249
143 4 21241059
144 4 21241749
145 4 21201783
146 4 21202473
147 4 21206283
148 4 21206973
149 4 21204543
150 4 21205233
151 4 21209043
152 4 21209733
153 4 21213543
154 4 21214233
155 4 21232473
156 4 21233163
157 4 21236973
158 4 21237663
159 4 21241473
160 4 21242163
161 4 21218343
162 4 21219033
163 4 21222843
164 4 21223533
165 4 21221103
166 4 21221793
167 4 21225603
168 4 21226293
169 4 21230103
170 4 21230793
171 4 21249033
172 4 21249723
173 4 21253533
174 4 21254223
175 4 21258033
176 4 21258723
177 4 21218757
178 4 21219447
179 4 21223257
180 4 21223947
181 4 21221517
182 4 21222207
183 4 21226017
184 4 21226707
185 4 21230517
186 4 21231207
187 4 21249447
188 4 21250137
189 4 21253947
190 4 21254637
191 4 21258447
192 4 21259137
193 4 21219171
194 4 21219861
195 4 21223671
196 4 21224361
197 4 21221931
198 4 21222621
199 4 21226431
200 4 21227121
201 4 21230931
202 4 21231621
203 4 21249861
204 4 21250551
205 4 21254361
206 4 21255051
207 4 21258861
208 4 21259551
209 4 21219585
210 4 21220275
211 4 21224085
212 4 21224775
213 4 21222345
214 4 21223035
215 4 21226845
216 4 21227535
217 4 21231345
218 4 21232035
219 4 21250275
220 4 21250965
221 4 21254775
222 4 21255465
223 4 21259275
224 4 21259965
225 4 21219999
226 4 21220689
227 4 21224499
228 4 21225189
229 4 21222759
230 4 21223449
231 4 21227259
232 4 21227949
233 4 21231759
234 4 21232449
235 4 21250689
236 4 21251379
237 4 21255189
238 4 21255879
239 4 21259689
240 4 21260379
241 4 21220413
242 4 21221103
243 4 21224913
244 4 21225603
245 4 21223173
246 4 21223863
247 4 21227673
248 4 21228363
249 4 21232173
250 4 21232863
251 4 21251103
252 4 21251793
253 4 21255603
254 4 21256293
255 4 21260103
256 4 21260793
257 4 21207801
258 4 21143096
259 4 21815450
260 8 44137111
261 8 44188780
262 8 44835173
263 12 69961555
264 12 71663500
265 12 71047828
266 16 96708344
267 16 98848150
268 16 101316697
269 20 126741646
270 20 128626382
271 20 130307580
272 31 198560382
273 13 75008772
0 0 1984
1 4 27520
2 4 27620
3 4 27720
4 4 27820
5 4 27920
6 4 28020
7 4 28120
8 4 28220
9 4 28320
10 4 28420
11 4 32420
12 4 32520
13 4 32620
14 4 32720
15 4 32820
16 4 32920
17 4 27580
18 4 27680
19 4 27780
20 4 27880
21 4 27980
22 4 28080
23 4 28180
24 4 28280
25 4 28380
26 4 28480
27 4 32480
28 4 32580
29 4 32680
30 4 32780
31 4 32880
32 4 32980
33 4 27640
34 4 27740
35 4 27840
36 4 27940
37 4 28040
38 4 28140
39 4 28240
40 4 28340
41 4 28440
42 4 28540
43 4 32540
44 4 32640
45 4 32740
46 4 32840
47 4 32940
48 4 33040
49 4 27700
50 4 27800
51 4 27900
52 4 28000
53 4 28100
54 4 28200
55 4 28300
56 4 28400
57 4 28500
58 4 28600
59 4 32600
60 4 32700
61 4 32800
62 4 32900
63 4 33000
64 4 33100
65 4 27760
66 4 27860
67 4 27960
68 4 28060
69 4 28160
70 4 28260
71 4 28360
72 4 28460
73 4 28560
74 4 28660
75 4 32660
76 4 32760
77 4 32860
78 4 32960
79 4 33060
80 4 33160
81 4 27820
82 4 27920
83 4 28020
84 4 28120
85 4 28220
86 4 28320
87 4 28420
88 4 28520
89 4 28620
90 4 28720
91 4 32720
92 4 32820
93 4 32920
94 4 33020
95 4 33120
96 4 33220
97 4 27880
98 4 27980
99 4 28080
100 4 28180
101 4 28280
102 4 28380
103 4 28480
104 4 28580
105 4 28680
106 4 28780
107 4 32780
108 4 32880
109 4 32980
110 4 33080
111 4 33180
112 4 33280
113 4 27940
114 4 28040
115 4 28140
116 4 28240
117 4 28340
118 4 28440
119 4 28540
120 4 28640
121 4 28740
122 4 28840
123 4 32840
124 4 32940
125 4 33040
126 4 33140
127 4 33240
128 4 33340
129 4 28000
130 4 28100
131 4 28200
132 4 28300
133 4 28400
134 4 28500
135 4 28600
136 4 28700
137 4 28800
138 4 28900
139 4 32900
140 4 33000
141 4 33100
142 4 33200
143 4 33300
144 4 33400
145 4 28060
146 4 28160
147 4 28260
148 4 28360
149 4 28460
150 4 28560
151 4 28660
152 4 28760
153 4 28860
154 4 28960
155 4 32960
156 4 33060
157 4 33160
158 4 33260
159 4 33360
160 4 33460
161 4 30460
162 4 30560
163 4 30660
164 4 30760
165 4 30860
166 4 30960
167 4 31060
168 4 31160
169 4 31260
170 4 31360
171 4 35360
172 4 35460
173 4 35560
174 4 35660
175 4 35760
176 4 35860
177 4 30520
178 4 30620
179 4 30720
180 4 30820
181 4 30920
182 4 31020
183 4 31120
184 4 31220
185 4 31320
186 4 31420
187 4 35420
188 4 35520
189 4 35620
190 4 35720
191 4 35820
192 4 35920
193 4 30580
194 4 30680
195 4 30780
196 4 30880
197 4 30980
198 4 31080
199 4 31180
200 4 31280
201 4 31380
202 4 31480
203 4 35480
204 4 35580
205 4 35680
206 4 35780
207 4 35880
208 4 35980
209 4 30640
210 4 30740
211 4 30840
212 4 30940
213 4 31040
214 4 31140
215 4 31240
216 4 31340
217 4 31440
218 4 31540
219 4 35540
220 4 35640
221 4 35740
222 4 35840
223 4 35940
224 4 36040
225 4 30700
226 4 30800
227 4 30900
228 4 31000
229 4 31100
230 4 31200
231 4 31300
232 4 31400
233 4 31500
234 4 31600
235 4 35600
236 4 35700
237 4 35800
238 4 35900
239 4 36000
240 4 36100
241 4 30760
242 4 30860
243 4 30960
244 4 31060
245 4 31160
246 4 31260
247 4 31360
248 4 31460
249 4 31560
250 4 31660
251 4 35660
252 4 35760
253 4 35860
254 4 35960
255 4 36060
256 4 36160
257 4 28480
258 4 73360
259 4 136960
260 8 240120
261 8 265320
262 8 314172
263 12 557752
264 12 688064
265 12 627432
266 16 883456
267 16 999872
268 16 1163820
269 20 1422708
270 20 1481508
271 20 1595496
272 31 2431232
273 13 500640
===*/

// Test strings created using Python.  These are used as base and modified in
// various ways.
/*
for i in xrange(256):
    print(chr(i).encode('base64'))

txt = 'foo bar quux baz'
for i in xrange(16):
    print(txt[0:i].encode('base64'))
*/
var testStrings = [
    '',

    'AA==',
    'AQ==',
    'Ag==',
    'Aw==',
    'BA==',
    'BQ==',
    'Bg==',
    'Bw==',
    'CA==',
    'CQ==',
    'Cg==',
    'Cw==',
    'DA==',
    'DQ==',
    'Dg==',
    'Dw==',
    'EA==',
    'EQ==',
    'Eg==',
    'Ew==',
    'FA==',
    'FQ==',
    'Fg==',
    'Fw==',
    'GA==',
    'GQ==',
    'Gg==',
    'Gw==',
    'HA==',
    'HQ==',
    'Hg==',
    'Hw==',
    'IA==',
    'IQ==',
    'Ig==',
    'Iw==',
    'JA==',
    'JQ==',
    'Jg==',
    'Jw==',
    'KA==',
    'KQ==',
    'Kg==',
    'Kw==',
    'LA==',
    'LQ==',
    'Lg==',
    'Lw==',
    'MA==',
    'MQ==',
    'Mg==',
    'Mw==',
    'NA==',
    'NQ==',
    'Ng==',
    'Nw==',
    'OA==',
    'OQ==',
    'Og==',
    'Ow==',
    'PA==',
    'PQ==',
    'Pg==',
    'Pw==',
    'QA==',
    'QQ==',
    'Qg==',
    'Qw==',
    'RA==',
    'RQ==',
    'Rg==',
    'Rw==',
    'SA==',
    'SQ==',
    'Sg==',
    'Sw==',
    'TA==',
    'TQ==',
    'Tg==',
    'Tw==',
    'UA==',
    'UQ==',
    'Ug==',
    'Uw==',
    'VA==',
    'VQ==',
    'Vg==',
    'Vw==',
    'WA==',
    'WQ==',
    'Wg==',
    'Ww==',
    'XA==',
    'XQ==',
    'Xg==',
    'Xw==',
    'YA==',
    'YQ==',
    'Yg==',
    'Yw==',
    'ZA==',
    'ZQ==',
    'Zg==',
    'Zw==',
    'aA==',
    'aQ==',
    'ag==',
    'aw==',
    'bA==',
    'bQ==',
    'bg==',
    'bw==',
    'cA==',
    'cQ==',
    'cg==',
    'cw==',
    'dA==',
    'dQ==',
    'dg==',
    'dw==',
    'eA==',
    'eQ==',
    'eg==',
    'ew==',
    'fA==',
    'fQ==',
    'fg==',
    'fw==',
    'gA==',
    'gQ==',
    'gg==',
    'gw==',
    'hA==',
    'hQ==',
    'hg==',
    'hw==',
    'iA==',
    'iQ==',
    'ig==',
    'iw==',
    'jA==',
    'jQ==',
    'jg==',
    'jw==',
    'kA==',
    'kQ==',
    'kg==',
    'kw==',
    'lA==',
    'lQ==',
    'lg==',
    'lw==',
    'mA==',
    'mQ==',
    'mg==',
    'mw==',
    'nA==',
    'nQ==',
    'ng==',
    'nw==',
    'oA==',
    'oQ==',
    'og==',
    'ow==',
    'pA==',
    'pQ==',
    'pg==',
    'pw==',
    'qA==',
    'qQ==',
    'qg==',
    'qw==',
    'rA==',
    'rQ==',
    'rg==',
    'rw==',
    'sA==',
    'sQ==',
    'sg==',
    'sw==',
    'tA==',
    'tQ==',
    'tg==',
    'tw==',
    'uA==',
    'uQ==',
    'ug==',
    'uw==',
    'vA==',
    'vQ==',
    'vg==',
    'vw==',
    'wA==',
    'wQ==',
    'wg==',
    'ww==',
    'xA==',
    'xQ==',
    'xg==',
    'xw==',
    'yA==',
    'yQ==',
    'yg==',
    'yw==',
    'zA==',
    'zQ==',
    'zg==',
    'zw==',
    '0A==',
    '0Q==',
    '0g==',
    '0w==',
    '1A==',
    '1Q==',
    '1g==',
    '1w==',
    '2A==',
    '2Q==',
    '2g==',
    '2w==',
    '3A==',
    '3Q==',
    '3g==',
    '3w==',
    '4A==',
    '4Q==',
    '4g==',
    '4w==',
    '5A==',
    '5Q==',
    '5g==',
    '5w==',
    '6A==',
    '6Q==',
    '6g==',
    '6w==',
    '7A==',
    '7Q==',
    '7g==',
    '7w==',
    '8A==',
    '8Q==',
    '8g==',
    '8w==',
    '9A==',
    '9Q==',
    '9g==',
    '9w==',
    '+A==',
    '+Q==',
    '+g==',
    '+w==',
    '/A==',
    '/Q==',
    '/g==',
    '/w==',

    'Zg==',
    'Zm8=',
    'Zm9v',
    'Zm9vIA==',
    'Zm9vIGI=',
    'Zm9vIGJh',
    'Zm9vIGJhcg==',
    'Zm9vIGJhciA=',
    'Zm9vIGJhciBx',
    'Zm9vIGJhciBxdQ==',
    'Zm9vIGJhciBxdXU=',
    'Zm9vIGJhciBxdXV4',
    'Zm9vIGJhciBxdXV4IA==',
    'Zm9vIGJhciBxdXV4IGI=',
    'Zm9vIGJhciBxdXV4IGJh',

    // Manually added
    'Z m9 vI\n\nG\r\r\nJh\t\tciB\t\txdXV4IGJh',
    'Zm==Zm9=Zm9v\n'
];

function concatenateTest() {
    // Concatenate test strings
    var csum = 0;
    testStrings.forEach(function (s1) {
        testStrings.forEach(function (s2) {
            csum += checksumString(Duktape.enc('jx', Duktape.dec('base64', s1 + s2)));
        });
    });
    print(csum);
}

print('concatenate');
concatenateTest();

function whitespaceMutateTest() {
    var test = [].concat(testStrings);
    var i, j, buf;

    // mutated byte
    test.forEach(function (str, idx) {
        var tmp, csum = 0;
        for (i = 0; i < str.length; i++) {
            for (j = 0; j < 512; j++) {
                tmp = str.substring(0, i) + String.fromCharCode(j) + str.substring(i + 1);
                try {
                    csum += checksumString(Duktape.enc('jx', Duktape.dec('base64', tmp)));
                } catch (e) {
                    csum += checksumString('error at: ' + i + ', ' + j);
                }
            }
        }
        print(idx, str.length, csum);
    });

    // inserted whitespace
    test.forEach(function (str, idx) {
        var tmp, csum = 0;
        for (i = 0; i <= str.length; i++) {
            for (j = 0; j < 4; j++) {
                tmp = str.substring(0, i) + ' \r\n\t'[j] + str.substring(i);
                try {
                    csum += checksumString(Duktape.enc('jx', Duktape.dec('base64', tmp)));
                } catch (e) {
                    csum += checksumString('error at: ' + i + ', ' + j);
                }
            }
        }
        print(idx, str.length, csum);
    });
}

print('whitespace and mutate test');
whitespaceMutateTest();
